/* ----------------------------------------------------------------------------

	pax.data.js Copyright (C) 2006, 2008 Mikkel Bergmann, Pointful

	Licence
	-------
	
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

	See lgpl.txt for licence details

---------------------------------------------------------------------------- */

/*
	Script: pax.data
		This class allows various ways of parsing of data
		
	Author:
		Mikkel Bergmann, <http://www.pointful.com>
*/

/*
	TODO: utalise jspon (www.jspon.org) to allow ORM manipulation.

*/

var pax = pax || {};
pax.data = pax.data || {};
pax.data.parse = pax.data.parse || {};

/*	Method: pax.data.parse.data.xmlDOM
	Parses an XML document into a Document Object Model object.
	
	Parameters:
		xmlDocument - an XML document to parse
		
	Note:
		* Attributes are accesed via '_attribute'
		* Values are accesed via '_value'

	Example:
		(start code)
			<a href='../people.xml'>people.xml</a><hr>
			<textarea id='pax.data.parse.xmlDOM.example1' cols=100 rows=16></textarea>
			
			[:.
				function parseXML( xml, txt, url ) {
					pax.$('pax.data.parse.xmlDOM.example1').value = pax.util.pprint( pax.data.parse.xmlDOM( xml ) );
				}
				pax.get( '../people.xml', parseXML );
			:]

		(end)
		This example retreives an XML file, parses it into an object, and pretty prints the result in a textarea.
*/
//	Note that some parts come from http://www.openjs.com/scripts/xml_parser/xml2array.js
pax.data.parse.xmlDOM = function( xmlDocument ) {
	var whitespace = new RegExp(/[^\s]/);	//	RegExp to find whitespace

	//	Process the xml data
	function xml2obj( xmlDoc, parent ) {
		var obj = {}, parentName = "";
		parent = parent || {};

		//	Child node
		var nodeValue = xmlDoc.nodeValue;
		if( xmlDoc.parentNode && xmlDoc.parentNode.nodeName && nodeValue && whitespace.test( nodeValue ) ) {
			obj[xmlDoc.parentNode.nodeName] = {};
			obj[xmlDoc.parentNode.nodeName]._value = nodeValue;
		}

		//	Parent node
		if( xmlDoc.nodeName && xmlDoc.nodeName.charAt(0) != "#" && xmlDoc.childNodes.length > 1 ) {
			parentName = xmlDoc.nodeName;
		}
		
		if( xmlDoc.childNodes.length == 1 ) {
			obj = xml2obj( xmlDoc.childNodes[0], parent );
		} else {	// Iterate on child nodes
			for( var i = 0; i < xmlDoc.childNodes.length; i++ ) {
				var temp = xml2obj( xmlDoc.childNodes[i], parent );
				if( temp ) {
					//	temp is an object like this: { key: value }, and here we get just the the key
					for( var key in temp ) { break;	};
					
					//	Repeated element
					if( obj[key] ) {
						//	We make a numerically indexed object here
						if( ! parent[key] ) {
							parent[key] = 0;
							obj[key] = { 0: obj[key] };
						}
						parent[key] += 1;
						obj[key][parent[key]] = temp[key]; //Members of of a numeric array
					} else {
						parent[key] = 0;
						obj[key] = temp[key];
						//	get the attributes
						if( xmlDoc.childNodes && xmlDoc.childNodes[i] && xmlDoc.childNodes[i].attributes ) {
							for( var j = 0; j < xmlDoc.childNodes[i].attributes.length; j++ ) {
								var nname = xmlDoc.childNodes[i].attributes[j].nodeName;
								if( nname ) {
									obj[key]['_attribute'] = obj[key]['_attribute'] || {};
									obj[key]['_attribute'][nname] = xmlDoc.childNodes[i].attributes[j].nodeValue;
								}
							}
						}
					}
				}
			}
		}

		if( parentName && obj ) {
			var temp = obj;
			obj = {};
			obj[parentName] = temp;
		}
		
		return obj;
	}

	return xml2obj( xmlDocument, 0 );
};